package han.thread;

import han.proof.CookieRepository;
import han.sql.DataSource;
import han.sql.InsertThread;

import java.sql.Timestamp;
import java.util.concurrent.ThreadPoolExecutor;

import static com.han.http.util.Print.printlnInfo;

/**
 * @author: Han
 * @date: 2018/8/10 10:19
 * @dscription: 监控线程, 监控当前线程运行状态和cookie状态
 */
public class MonitorThread extends Thread {
    private InsertThread insertThread;
    private ThreadPoolExecutor poolExecutor;
    private CookieRepository cookieRepository;
    private boolean isRunning;

    public MonitorThread(InsertThread insertThread, ThreadPoolExecutor poolExecutor, CookieRepository cookieRepository) {
        this.insertThread = insertThread;
        this.poolExecutor = poolExecutor;
        this.cookieRepository = cookieRepository;
        isRunning = true;
        setName("Thread-监控");
    }

    @Override
    public void run() {
        printlnInfo(getName() + " 监控线程启动");
        while (isRunning) {
            try {
                Thread.sleep(1000 * 20);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            long completedTaskCount = poolExecutor.getCompletedTaskCount();
            int poolSize = poolExecutor.getPoolSize();
            int largestCount = poolExecutor.getLargestPoolSize();
            int[] cookieStatus = cookieRepository.getStatus();
            Timestamp timestamp = new Timestamp(System.currentTimeMillis());
            printlnInfo(String.format("%s 当前线程数:%d,完成线程数:%d,最多线程数:%d\n" +
                            "[INFO]%ty-%tm-%td %tH:%tM:%tS %s 当前可用cookie:%d,暂时封禁:%d,登陆过期/永久封禁:%d",
                    getName(), poolSize, completedTaskCount, largestCount, timestamp, timestamp, timestamp, timestamp,
                    timestamp, timestamp, getName(), cookieStatus[0], cookieStatus[1], cookieStatus[2]));
            //暂时没有可用cookie
            if (cookieStatus[0] == 0 && insertThread.hasData()) {
                executeAll();
                //如果没有可用cookie，且数据库操作线程中已全部清空，关闭数据库连接池
                DataSource.closePool();
            }
            //如果线程池中只剩监控线程和数据库操作线程
            if (poolSize == 2) {
                if (insertThread.hasData()) {
                    //如果还有数据未被执行,全部执行
                    executeAll();
                }else {
                    //如果没有可用cookie，且数据库操作线程中已全部清空，关闭数据库连接池
                    DataSource.closePool();
                    //数据库操作线程关闭
                    insertThread.close();
                    //关闭监控线程
                    isRunning = false;
                }
            }
        }
        printlnInfo(getName() + " 监控线程关闭");
    }

    /**
     * 执行全部数据库操作
     */
    private void executeAll() {
        insertThread.executeUpdateFinanceProIdAtOnce();
        insertThread.executeInsertFinanceProInfoAtOnce();
        insertThread.executeInsertInvestOrgIdAtOnce();
        insertThread.executeInsertFinanceProIdAtOnce();
        insertThread.executeInsertInvestOrgInfoAtOnce();
    }
}
